#include <iostream>
#include <string>
#include <cstdio>
#include <pthread.h>
#include <cstring>
#include <unistd.h>
#include <thread>
using namespace std;

int tickets = 10000;//加锁保证共享资源的安全
pthread_mutex_t mutex;//后面说
void *threadRoutine(void *name)
{
    string tname = static_cast<const char *>(name);
    while (true)
    {
        pthread_mutex_lock(&mutex);//所有线程都要在访问前加锁，所以线程都要遵循这个规则
        if (tickets > 0)//多个线程同时进来，都在--，所以会导致票数会抢到负数
        {
            usleep(2000); // 模拟抢票花费的时间
            cout << tname << " get a ticket: " << tickets-- << endl;
            pthread_mutex_unlock(&mutex);//解锁
        }
        else
        {
            pthread_mutex_unlock(&mutex);//解锁
            break;
        }

        //后面还有动作
        usleep(1000);//充当抢完一张票，后续动作

    }
    return nullptr;
}
int main()
{
    pthread_mutex_init(&mutex,nullptr);
    pthread_t t[4];
    int n = sizeof(t) / sizeof(t[0]);
    for (int i = 0; i < n; i++)
    {
        char *data = new char[64];
        snprintf(data, 64, "thread--%d", i + 1);
        pthread_create(t + i, nullptr, threadRoutine, data);
    }
    for (int i = 0; i < n; i++)
    {
        pthread_join(t[i], nullptr);
    }
    pthread_mutex_destroy(&mutex);
    return 0;
}

// void run1()
// {
//     while(true)
//     {
//         cout<<"thread 1"<<endl;
//         sleep(1);
//     }
// }
// void run2()
// {
//     while(true)
//     {
//         cout<<"thread 2"<<endl;
//         sleep(1);
//     }
// }
// void run3()
// {
//     while(true)
//     {
//         cout<<"thread 3"<<endl;
//         sleep(1);
//     }
// }
// //c++11创建多线程的方法
// int main()
// {
//     thread th1(run1);//语言层面接口
//     thread th2(run2);
//     thread th3(run3);

//     th1.join();
//     th2.join();
//     th3.join();
//     return 0;
// }

// //int g_val=100;//全局变量，地址是一样的，被所以线程共享
// __thread int g_val=100;//加上__thread,就不被线程共享了,变成了每个线程私有的
// string hexAddr(pthread_t tid)//将10进制转出16进制
// {
//     char buffer[64];
//     snprintf(buffer,sizeof(buffer),"0x%x",tid);
//     return buffer;
// }
// void *threadRoutine(void *args)
// {
//     //pthread_detach(pthread_self());//自己分离,没有问题,但是，在main函数中，加个sleep（1）会出问题
//     //可能这个线程被创建的时候，因为被调度问题，这个一行都没调度，但主线程立即就join，主线程可能不知道这个函数被分离
//     string name = static_cast<const char *>(args);
//     int cnt = 5;//t1,t2,t3线程都有这个变量，每个都有一个
//     while (cnt)
//     {
//         //cout << name << " : " << cnt-- <<" : "<< hexAddr(pthread_self())<<" &cnt: "<<&cnt<< endl;//虽然是同一个变量，但打印出来的cnt地址绝对不一样，在不同的栈空间里
//         cout<<" g_val: "<<g_val++<<", &g_val "<<&g_val<<endl;
//         sleep(1);
//     }
//     return nullptr;
// }
// int main()
// {
//     //pthread_t tid;
//     //pthread_create(&tid, nullptr, threadRoutine, (void *)"thread 1");//线程被创建的时候，谁先执行不确定

//     pthread_t t1,t2,t3;
//     pthread_create(&t1, nullptr, threadRoutine, (void *)"thread 1");
//     pthread_create(&t2, nullptr, threadRoutine, (void *)"thread 2");
//     pthread_create(&t3, nullptr, threadRoutine, (void *)"thread 3");

//     pthread_join(t1, nullptr);
//     pthread_join(t2, nullptr);
//     pthread_join(t3, nullptr);

//     // while(true)
//     // {
//     //     cout<<" main thread: "<<hexAddr(pthread_self())<<" new thread id: "<<hexAddr(tid)<<endl;
//     //     sleep(1);
//     // }

//     // 线程分离
//     // pthread_detach(tid);//创建线程后，立马分离
//     // 一个线程被分离了，就不需要join了
//     //sleep(1);
//     // int n = pthread_join(tid, nullptr);
//     // if (n != 0)
//     // {
//     //     cerr << " error: " << n << " : " << strerror(n) << endl;
//     // }
//     return 0;
// }